//
//	File Name   :	VertexFormat.cpp
//	Description :	VertexFormat implementation file.
//	Author		:	William McVicar
//  Mail		:	mcvicar.william@gmail.com
//

//  Precompiled Header
#include "CommonDefines.h"

//  Library Includes

//  Local Includes

//  This includes
#include "VertexFormatBase.h"

//	Macros

//  Static Variables
i32 Protein::VertexFormatBase::sm_iSemanticSize[ SF_QUANTITY ] =
{
	0,  // SF_NONE
    4,  // SF_FLOAT1
    8,  // SF_FLOAT2
    12, // SF_FLOAT3
    16, // SF_FLOAT4
    2,  // SF_HALF1
    4,  // SF_HALF2
    6,  // SF_HALF3
    8,  // SF_HALF4
    4,  // SF_UBYTE4
    2,  // SF_SHORT1
    4,  // SF_SHORT2
    8   // SF_SHORT4
};

//  Static Function Prototypes

//  Implementation

namespace Protein
{

VertexFormatBase::VertexFormatBase( u32 _uiNumAttributes )
: m_uiNumAttributes( _uiNumAttributes )
, m_uiStride( 0 )
{
	memset( &m_VertElems, 0, sizeof( tVertElem ) * FL_MAX_ATTRIBUTES );
}

VertexFormatBase::~VertexFormatBase()
{

}

void VertexFormatBase::SetElement( i32 _iElementIndex, u32 _uiOffset, eSemanticType _eType, eSemanticFormat _eFormat )
{
	tVertElem& elem = m_VertElems[ _iElementIndex ];

	elem.eFormat  = _eFormat;
	elem.eType	  = _eType;
	elem.uiOffset = _uiOffset;
}

void VertexFormatBase::GetElement( i32 _iElementIndex, u32& _uiOffset, eSemanticType& _eType, eSemanticFormat& _eFormat ) const
{
	_eFormat  = m_VertElems[ _iElementIndex ].eFormat;
	_eType	  = m_VertElems[ _iElementIndex ].eType;
	_uiOffset = m_VertElems[ _iElementIndex ].uiOffset;
}

VertexFormatBase* VertexFormatBase::Create( u32 _uiNumAttributes, ... )
{
	VertexFormatBase* pBase = new VertexFormatBase( _uiNumAttributes );

	va_list arguments;
	va_start( arguments, _uiNumAttributes );

	u32 stride = 0;
	for( u32 i = 0; i < _uiNumAttributes; ++i )
	{
		eSemanticType   eType  = va_arg( arguments, eSemanticType );
		eSemanticFormat eFormat = va_arg( arguments, eSemanticFormat ); 
		pBase->SetElement( i, stride, eType, eFormat );
		stride += sm_iSemanticSize[ eFormat ];
	}

	pBase->m_uiStride = stride;

	va_end( arguments );
	return pBase;
}

}